from django.urls import path
from django.urls import re_path
from django.shortcuts import HttpResponse
from django.shortcuts import render
from django.shortcuts import redirect
from django.utils.safestring import mark_safe
from django.urls import reverse
from types import FunctionType
from django.forms import ModelForm
from django.db.models import Q
from django.db.models.fields.related import ForeignKey
from django.db.models.fields.related import ManyToManyField
from django.http import QueryDict
import functools

class ModelConfigMapping(object):
    '''

    '''
    def __init__(self,model,config,prev):
        self.model=model
        self.config=config
        self.prev=prev

def get_choice_text(field,head):
    '''
    获取choice对应的内容
    :param field:字段名称
    :param head:表头名称
    :return:
    '''
    def inner(self,row=None,header=False):
        if header:
            return head
        func_name="get_{}_display".format(field)
        return getattr(row,func_name)()
    return inner

class Row(object):
    '''
    返回前端展示的组合搜索的选项
    '''
    def __init__(self,data_list,option,query_dict):
        '''
        :param data_list: queryset
        :param option:    组合搜索的填写 需要展示组合搜索的选项
        '''
        self.data_list=data_list        #数据库中的获取的queryset
        self.option=option              #Option 对象
        self.query_dict=query_dict      #url 中的 原来的路径以及搜索条件
    def __iter__(self):
        yield '<div class="whole">'
        total_query_dict=self.query_dict.copy()  #request.GET的拷贝
        total_query_dict._mutable=True           #字段可以修改 打开开关
        origin_value_list=self.query_dict.getlist(self.option.field)   #Option 对象中的field的  搜索条件 存在

        ###########全部的实现 ###############
        if origin_value_list:
            #如果原本的搜索条件存在
            total_query_dict.pop(self.option.field)
            yield '<a href="?{}">全部</a>'.format(total_query_dict.urlencode())
        else:
            yield '<a class="active" href="?{}">全部</a>'.format(total_query_dict.urlencode())
        yield '</div>'
        yield '<div class="others">'
        ###########全部的实现 ###############

        for item in self.data_list: #item queryset 中一个对象
            text=self.option.get_text(item)  #组合搜索的a标签的  title
            val=self.option.get_value(item)  #组合搜索的a标签 的  url
            query_dict=self.query_dict.copy()   #获取原来的搜索条件
            query_dict.mutable=True             #把可以修改 打开

            if not self.option.is_multi:
                #单选的情况
                if str(val) in origin_value_list:
                    query_dict.pop(self.option.field)
                    yield '<a class="active" href="?{}">{}</a>'.format(query_dict.urlencode(),text)
                else:
                    query_dict[self.option.field]=val
                    yield '<a href="?{}">{}</a>'.format(query_dict.urlencode(), text)
            else:
                #多选的情况
                multi_value_list=query_dict.getlist(self.option.field)
                if str(val) in origin_value_list:
                    multi_value_list.remove(str(val))
                    query_dict.setlist(self.option.field,multi_value_list)
                    yield '<a class="active" href="?{}">{}</a>'.format(query_dict.urlencode(),text)
                else:
                    multi_value_list.append(val)
                    query_dict.setlist(self.option.field,multi_value_list)
                    yield '<a  href="?{}">{}</a>'.format(query_dict.urlencode(),text)

        yield '</div>'

class Option(object):
    '''
    filter_list []  中的 每一项的类
    list_filter = [
        Option('name',condition={'id__gt':9},text_func=lambda x:x.name),
        Option('level',is_choice=True,text_func=lambda x:x[1]),
        Option('user',text_func=lambda x:x.title),
        Option('tel',text_func=lambda x:x.tel)
    ] # 配置项多
    '''
    def __init__(self,field,condition=None,is_choice=False,text_func=None,value_func=None,is_multi=False):
        '''
        组合搜索选项的每一项的初始化
        :param field:
        :param condition:
        :param is_choice:
        :param text_func:
        '''
        self.field=field
        self.is_choice=is_choice
        if not condition:
            self.condition={}
        else:
            self.condition=condition
        self.text_func=text_func   #前端显示的字段 title
        self.value_func=value_func #前端显示的 url
        self.is_multi=is_multi #组合搜索是否可以多选

    def get_queryset(self,_field,model_class,query_dict):
        '''
        获取组合搜索的前端显示的 选项
        :param _field:       字段   model class 中的
        :param model_class:  model class 对象
        :param query_dict:   request.GET  的拷贝
        :return:
        '''
        if isinstance(_field,ForeignKey) or isinstance(_field,ManyToManyField):
            '''
            foreignkey  or  manytomanyfield  的情况
            '''
            row=Row(_field.remote_field.model.objects.filter(**self.condition),self,query_dict)
        else:
            '''
            choices 的情况
            '''
            if self.is_choice:
                row=Row(_field.choices,self,query_dict)
            #其他情况
            else:
                row=Row(model_class.objects.filter(**self.condition),self,query_dict)
        return row

    def get_text(self,item):
        '''
        获取显示字段的a标签的值的 方法
        :param item:
        :return:
        '''
        if self.text_func:
            return self.text_func(item)
        if self.is_choice:
            return item[1]
        else:
            return str(item)

    def get_value(self,item):
        '''
        获取显示的字段的 url 的构造的值显示的方法
        :param item:
        :return:
        '''
        if self.value_func:
            return self.value_func(item)
        if self.is_choice:
            return item[0]
        else:
            return item.pk
class ChangeList(object):
    '''
    封装列表页面所需的功能
    '''
    def __init__(self,config,queryset,q,search_list,page):
        self.q=q  #模糊搜索条件
        self.search_list=search_list    #模糊搜索的字段列表
        self.page=page
        self.config=config             # StacConfig
        self.action_list=[{'name':func.__name__,'text':func.text} for func in config.get_action_list()]  # 批量操作 的方法列表
        self.add_btn=config.get_add_btn()           #添加按钮
        self.queryset=queryset                      # 数据库中获取的数据集合
        self.list_display=config.get_list_display() #展示用的字段 列表
        self.filter_list=config.get_filter_list()   #组合搜索用到的字段 列表

    def gen_filter_row_list(self):
        '''
        返回前台需要的 组合搜索的a 标签 集合
        :return:
        '''
        for item in self.filter_list:
            _field=self.config.model_class._meta.get_field(item.field)
            yield item.get_queryset(_field,self.config.model_class,self.config.request.GET)

class StackConfig(object):
    '''
    生成四个view视图函数 为每个mode
    '''

    order_by = []  # 数据库中的排序 字段 列表
    list_display = []  # 数据库中展示 字段 列表
    model_form_class=None # modelform 类

    def __init__(self,model_class,site,prev):
        '''
        构造函数
        :param model_class:
        :param site:
        '''
        self.model_class=model_class
        self.site=site
        self.request=None
        self.back_condition_key='_filter'  #模块搜索的 用
        self.prev=prev
    def display_checkbox(self,row=None,header=False):
        '''
        多选框的实现
        :param row:
        :param header:
        :return:
        '''
        if header:
            return '选择'
        else:
            return mark_safe('<input type="checkbox" name="pk" value="{}">'.format(row.pk))

    def display_edit(self,row=None,header=False):
        '''
        编辑展示的实现
        :param row:
        :param header:
        :return:
        '''
        if header:
            return '编辑'
        else:
            return mark_safe('<a href="%s"><i class="fa fa-edit" aria-hidden="true"></i></a></a>' % self.reverse_edit_url(row))

    def display_del(self,row=None,header=False):
        '''
        删除展示的实现
        :param row:
        :param header:
        :return:
        '''
        if header:
            return '删除'
        else:
            return mark_safe('<a href="%s"><i class="fa fa-trash-o" aria-hidden="true"></i></a></a>' % self.reverse_del_url(row))

    def display_edit_del_display(self,row=None,header=False):
        '''
        编辑 删除  的展示的实现
        :param row:
        :param header:
        :return:
        '''
        if header:
            return '操作'
        else:
            tpl = """<a href="{}"><i class="fa fa-edit" aria-hidden="true"></i></a></a> |
                    <a href="{}"><i class="fa fa-trash-o" aria-hidden="true"></i></a>
                    """.format(self.reverse_edit_url(row), self.reverse_del_url(row),)
            return mark_safe(tpl)


    def get_add_btn(self):
        '''
        获得添加按钮
        :return:
        '''
        return mark_safe('<a href="%s" class="btn btn-success">添加</a>' % self.reverse_add_url())

    def get_model_form_class(self):
        '''
        获得ModelForm类
        :return:
        '''
        if self.model_form_class:
            return self.model_form_class

        else:
            class AddModelForm(ModelForm):
                class Meta:
                    model=self.model_class
                    fields='__all__'
            return AddModelForm


    def get_order_by(self):
        '''
        获取排队列表
        :return:
        '''
        val=[]
        val.extend(self.order_by)
        return val

    # def get_list_display(self):
    #     '''
    #     获取页面展示字段列表
    #     :return:
    #     '''
    #     val=[]
    #     val.extend(self.list_display)
    #     val.append(StackConfig.display_edit_del_display)
    #     return val

    def get_list_display(self):
        val = []
        val.extend(self.list_display)
        val.append(StackConfig.display_edit)
        val.append(StackConfig.display_del)
        return val

    def multi_delete(self,request):
        '''
        批量删除
        :param request:
        :return:
        '''
        pk_list=request.POST.getlist('pk')
        self.model_class.objects.filter(pk__in=pk_list).delete()
    multi_delete.text='批量删除'

    action_list=[]  #执行批量操作的方法列表  用于前台页面展示
    search_list=[]  #模糊搜索的列表 用于前台页面展示
    filter_list=[]  #组合搜索的列表 用于前台页面展示

    def get_action_list(self):
        '''
        获取 批量操作列表的方法
        :return:
        '''
        val=[]
        val.extend(self.action_list)
        return val

    def get_action_dict(self):
        '''
        获取 批量操作的字典
        :return:
        '''
        val={}
        for item in self.get_action_list():
            val[item.__name__]=item
        return val

    def get_search_list(self):
        '''
        获取 用于模糊搜索的字段列表
        :return:
        '''
        val=[]
        val.extend(self.search_list)
        return val

    def get_search_condition(self,request):
        '''
        构造模糊搜索条件
        :param request:
        :return:
        '''
        search_list=self.get_search_list()
        q=request.GET.get('q','')
        con=Q()
        con.connector='OR'  #模糊搜索的构建
        if q:  #搜索条件
            for item in search_list:
                con.children.append(('{}__contains'.format(item),q))
        return search_list,q,con

    def get_filter_list(self):
        '''
        获取组合搜索的列表
        :return:
        '''
        val=[]
        val.extend(self.filter_list)
        return val

    def get_filter_list_condition(self):
        '''
        获取组合搜索的条件   用于 数据库的filter 条件
        :return:
        '''
        comb_condition={}
        for option in self.get_filter_list():
            element=self.request.GET.getlist(option.field)   #查询url中是否有组合搜索的条件
            if element:
                comb_condition['{}__in'.format(option.field)]=element  #  拼接组合搜索的条件
        return comb_condition

    def get_queryset(self):
        '''
        获取数据的钩子函数
        :return:
        '''
        queryset=self.model_class.objects
        return queryset

    def save(self,form,modify=False):
        '''
        form 的 save方法的钩子函数
        :param form: form 对象
        :param modify: True 表示要修改 False 表示 新增
        :return:
        '''
        return form.save()
    def list_view(self,request):
        '''
        查看页面的实现
        :param request:
        :return:
        '''
        #### 执行批量操作开始 ####
        if request.method=='POST':
            action_name=request.POST.get('action')
            action_dict=self.get_action_dict()
            if action_name not in action_dict:
                return HttpResponse('非法请求')
            else:
                response=getattr(self,action_name)(request)
                if response:
                    return response
        #### 执行批量操作结束 ####

        #### 模糊搜索的处理 ####
        search_list,q,con=self.get_search_condition(request)

        #### 处理queryset的钩子函数 #########
        origin_queryset=self.get_queryset()
        ##### 组合搜索的搜索条件获取 ########
        filter_condition=self.get_filter_list_condition()
        ####  处理分页 ####
        from stack.utils.pagination import Pagination
        # queryset 的钩子函数会影响到分页
        # total_count=self.model_class.objects.filter(con).filter(**filter_condition).count() #查询到的数据条数
        total_count = origin_queryset.filter(con).filter(**filter_condition).count()  # 查询到的数据条数
        query_params=request.GET.copy()
        query_params._mutable=True  #   获取原来的搜索条件
        page=Pagination(request.GET.get('page'),total_count,request.path_info,query_params,per_page=3)
        ## queryset的钩子函数 影响到 数据的获取
        # queryset=self.model_class.objects.filter(con).filter(**filter_condition).order_by(*self.get_order_by())[page.start:page.end]
        queryset=origin_queryset.filter(con).filter(**filter_condition).order_by(*self.get_order_by())[page.start:page.end]
        cl=ChangeList(self,queryset,q,search_list,page)
        context={'cl':cl}
        #######组合搜索  优化前的代码
        # #### 组合搜索前台展示 ####
        # filter_list=self.get_filter_list()  #获取组合搜索 的 字段
        # filter_row_list=[]  #组合搜索的前段 的展示  a标签
        # for option in filter_list:
        #     _field=self.model_class._meta.get_field(option.field)  #获取该字段的 在数据库中的 字段
        #     row=option.get_queryset(_field,self.model_class,request.GET)  # 生成  显示的对象 a标签
        #     filter_row_list.append(row)                             #添加 a标签 到列表中
        # context={'cl':cl,'list_filter_rows':filter_row_list}
        return render(request,'stack/list.html',context)

        ##############################################################################################################
        ##############################################################################################################
        #################################### 优化代码部分开始   #########################################################
        ### 批量操作列表  页面展示 ####
        # action_list=self.get_action_list()
        # action_list=[{'name':func.__name__,'text':func.text} for func in action_list]
        # ### 添加按钮  页面展示 ###
        # add_btn=self.get_add_btn()
        #
        # list_display=self.get_list_display()
        # header_list=[]  #展示表格 表头
        # body_list=[]    #展示表格 表体
        # #### 处理表头信息开始 ####
        # if list_display:
        #     for name_or_func in list_display:
        #         if isinstance(name_or_func,FunctionType):
        #             verbose_name=name_or_func(self,header=True)
        #         else:
        #             verbose_name=self.model_class._meta.get_field(name_or_func).verbose_name
        #         header_list.append(verbose_name)
        # else:
        #     header_list.append(self.model_class._meta.model_name)
        # #### 处理表头信息结束 ####
        # for row in queryset:
        #     row_list=[]  # 数据库 每一行的数据
        #     if not list_display:
        #         row_list.append(row)
        #         body_list.append(row_list)
        #         continue
        #     else:
        #         for name_or_func in list_display:
        #             if isinstance(name_or_func,FunctionType):
        #                 val=name_or_func(self,row=row)
        #             else:
        #                 val=getattr(row,name_or_func)
        #             row_list.append(val)
        #         body_list.append(row_list)
        #
        # return render(request,'stack/list.html',{'header_list':header_list,'body_list':body_list,'add_btn':add_btn,'action_list':action_list,'search_list':search_list,'q':q})
        ##############################################################################################################
        ##############################################################################################################
        #################################### 优化代码部分结束   #########################################################
    def add_view(self,request):
        '''
        添加页面的实现
        :param request:
        :return:
        '''
        #获得添加的ModelForm类
        AddModelForm=self.get_model_form_class()
        # print(self.__dict__)
        # from sakucrm.config.customer import PrivateCustomerConfig
        # print(isinstance(self,PrivateCustomerConfig))
        if request.method=='GET':
            '''
            get 方法
            '''
            form=AddModelForm()
            return render(request,'stack/change.html',{'form':form})

        if request.method=='POST':
            '''
            post 方法
            '''
            form=AddModelForm(request.POST)
            if form.is_valid():
                # form.save()  #调用save的钩子函数
                self.save(form,modify=False)

                return redirect(self.reverse_list())
            else:
                return render(request,'stack/change.html',{'form':form})

    def change_view(self,request,pk):
        ''''
        编辑页面的实现
        '''
        obj=self.model_class.objects.filter(pk=pk).first()
        # print(self.__dict__)
        # print('编辑---', self.request.path_info)
        # print(self.prev)
        # from sakucrm.config.customer import PrivateCustomerConfig
        # print(isinstance(self, PrivateCustomerConfig))
        if not obj:
            return HttpResponse('数据不存在')

        EditModelForm=self.get_model_form_class()
        if request.method=='GET':
            form=EditModelForm(instance=obj)
            return render(request,'stack/change.html',{'form':form})
        if request.method=='POST':
            form=EditModelForm(instance=obj,data=request.POST)
            if form.is_valid():
                # form.save() 调用form的save 钩子函数
                self.save(form,modify=True)


                return redirect(self.reverse_list())
            else:
                return render(request,'stack/change.html',{'form':form})

    def delete_view(self,request,pk):
        '''
        删除页面的实现
        :param request:
        :return:
        '''

        if request.method=='GET':
            list_url=self.reverse_list()
            return render(request,'stack/delete.html',{"list_url":list_url})

        if request.method=='POST':
            obj=self.model_class.objects.filter(pk=pk).first()
            if not obj:
                return HttpResponse('数据不存在')
            else:
                self.model_class.objects.filter(pk=pk).delete()
                return redirect(self.reverse_list())

    def wrapper(self,func):
        '''
        装饰器
        :param func:
        :return:
        '''
        @functools.wraps(func)
        def inner(request,*args,**kwargs):
            self.request=request
            return func(request,*args,**kwargs)
        return inner

    def get_urls(self):
        '''
        生成url
        :return:
        '''
        info=self.model_class._meta.app_label,self.model_class._meta.model_name
        urlpatterns=[
            # path('list/',self.wrapper(self.list_view),name='{}_{}_list'.format(*info)),
            # path('add/',self.wrapper(self.add_view),name='{}_{}_add'.format(*info)),
            # re_path('change/(?P<pk>\d+)/', self.wrapper(self.change_view), name='{}_{}_change'.format(*info)),
            # re_path('delete/(?P<pk>\d+)/', self.wrapper(self.delete_view), name='{}_{}_delete'.format(*info)),
            path('list/', self.wrapper(self.list_view), name=self.get_list_url_name),
            path('add/',self.wrapper(self.add_view),name=self.get_add_url_name),
            path('change/<int:pk>/',self.wrapper(self.change_view),name=self.get_change_url_name),
            re_path('delete/(?P<pk>\d+)/',self.wrapper(self.delete_view), name=self.get_del_url_name),
        ]
        extra=self.extra_url()
        if extra:
            urlpatterns.extend(extra)
        return urlpatterns

    @property
    def get_list_url_name(self):
        '''
        获取list url的别名
        :return:
        '''
        app_label=self.model_class._meta.app_label
        model_name=self.model_class._meta.model_name
        if self.prev:
            name='{}_{}_{}_list'.format(app_label,model_name,self.prev)
        else:
            name='{}_{}_list'.format(app_label,model_name)
        return name

    @property
    def get_add_url_name(self):
        '''
        获取 add url 别名
        :return:
        '''
        app_label = self.model_class._meta.app_label
        model_name = self.model_class._meta.model_name
        if self.prev:
            name ='{}_{}_{}_add'.format(app_label,model_name,self.prev)
        else:
            name = '{}_{}_add'.format(app_label, model_name)
        return name

    # @property
    # def get_change_url_name(self):
    #     '''
    #     获取 edit url 别名
    #     :return:
    #     '''
    #     app_label = self.model_class._meta.app_label
    #     model_name = self.model_class._meta.model_name
    #     if self.prev:
    #         name = '{}_{}_{}_change'.format(app_label,model_name,self.prev)
    #     else:
    #         name = '{}_{}_change'.format(app_label, model_name)
    #     return name

    @property
    def get_change_url_name(self):
        app_label = self.model_class._meta.app_label
        model_name = self.model_class._meta.model_name
        if self.prev:
            name = '%s_%s_%s_change' % (app_label, model_name, self.prev)
        else:
            name = '%s_%s_change' % (app_label, model_name)
        return name

    @property
    def get_del_url_name(self):
        '''
        获取 删除 url 的别名
        :return:
        '''
        app_label = self.model_class._meta.app_label
        model_name = self.model_class._meta.model_name
        if self.prev:
            name = '{}_{}_{}_delete'.format(app_label,model_name,self.prev)
        else:
            name = '{}_{}_delete'.format(app_label,model_name)
        return name

    def extra_url(self):
        pass

    # def reverse_edit_url(self,row):
    #     '''
    #     反向生成 添加/编辑 页面的url
    #     :param row:
    #     :return:
    #     '''
    #     # app_label=self.model_class._meta.app_label
    #     # model_name=self.model_class._meta.model_name
    #
    #     namespace=self.site.namespace
    #     # name='{}:{}_{}_change'.format(namespace,app_label,model_name)
    #     name = '{}:{}'.format(namespace,self.get_change_url_name)
    #     edit_url=reverse(name,kwargs={'pk':row.pk})
    #     if not self.request.GET:
    #         return edit_url
    #     param_str = self.request.GET.urlencode()  # q=嘉瑞&page=2
    #     new_query_dict = QueryDict(mutable=True)
    #     new_query_dict[self.back_condition_key] = param_str
    #     edit_url = "{}?{}".format(edit_url, new_query_dict.urlencode(),)
    #     return edit_url
    #     # if not self.request.GET:
    #     #     return edit_url
    #     # else:
    #     #     param_str=self.request.GET.urlencode()
    #     #     new_query_dict=QueryDict(mutable=True)
    #     #     new_query_dict[self.back_condition_key]=param_str
    #     #     edit_url=reverse("{}?{}".format(edit_url,new_query_dict.urlencode()))
    #     # return edit_url

    def reverse_edit_url(self, row):
        namespace = self.site.namespace
        name = '%s:%s' % (namespace, self.get_change_url_name)
        edit_url = reverse(name, kwargs={'pk': row.pk})

        if not self.request.GET:
            return edit_url
        param_str = self.request.GET.urlencode()  # q=嘉瑞&page=2
        new_query_dict = QueryDict(mutable=True)
        new_query_dict[self.back_condition_key] = param_str
        edit_url = "%s?%s" % (edit_url, new_query_dict.urlencode(),)

        return edit_url

    def reverse_del_url(self,row):
        '''
        反向生成 删除 页面的 url
        :param row:
        :return:
        '''
        # app_label=self.model_class._meta.app_label
        # model_name=self.model_class._meta.model_name
        namespace=self.site.namespace
        name='{}:{}'.format(namespace,self.get_del_url_name)
        delete_url=reverse(name,kwargs={'pk':row.pk})
        if not self.request.GET:
            return delete_url

        param_str = self.request.GET.urlencode()
        new_query_dict = QueryDict(mutable=True)
        new_query_dict[self.back_condition_key] = param_str
        delete_url = '{}?{}'.format(delete_url, new_query_dict.urlencode())
        return delete_url

    def reverse_add_url(self):
        '''
        反向生成添加 页面的url
        :param row:
        :return:
        '''
        # app_label=self.model_class._meta.app_label
        # model_name=self.model_class._meta.model_name
        namespace=self.site.namespace
        name='{}:{}'.format(namespace,self.get_add_url_name)
        add_url=reverse(name)
        if not self.request.GET:
            return add_url
        param_str=self.request.GET.urlencode()
        new_query_dict=QueryDict(mutable=True)
        new_query_dict[self.back_condition_key]=param_str
        add_url='{}?{}'.format(add_url,new_query_dict.urlencode())
        return add_url

    def reverse_list(self):
        '''
        反向生成 展示列表页面的url
        :return:
        '''
        # app_label=self.model_class._meta.app_label
        # model_name=self.model_class._meta.model_name

        namespace=self.site.namespace
        name='{}:{}'.format(namespace,self.get_list_url_name)
        list_url=reverse(name)
        origin_condition=self.request.GET.get(self.back_condition_key)
        if not origin_condition:
            return list_url
        else:
            list_url='{}?{}'.format(list_url,origin_condition)
            return list_url

    @property
    def urls(self):
        '''
        生成url
        :return:
        '''
        return self.get_urls()

class AdminSite(object):

    def __init__(self):
        # self._register={}
        self._register = []
        self.app_name='stack'
        self.namespace='stack'

    def register(self,model_class,stack_config=None,prev=None):
        if not stack_config:
            stack_config=StackConfig
        # self._register[model_class]=stack_config(model_class,self)
        self._register.append(ModelConfigMapping(model_class, stack_config(model_class, self, prev), prev))
    def get_urls(self):
        urlpatterns=[]
        # for k,v in self._register.items():
        for item in self._register:
            # app_label=k._meta.app_label
            app_label=item.model._meta.app_label
            # model_name=k._meta.model_name
            model_name=item.model._meta.model_name
            # urlpatterns.append(path('{}/{}/'.format(app_label,model_name),(v.urls,None,None)))
            if item.prev:
                temp=path('{}/{}/{}/'.format(app_label, model_name,item.prev), (item.config.urls, None, None))
            else:
                temp=path('{}/{}/'.format(app_label, model_name), (item.config.urls, None, None))
            urlpatterns.append(temp)
        return urlpatterns

    @property
    def urls(self):
        return self.get_urls(),self.app_name,self.namespace

site=AdminSite()
